package com.zl.rbac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zl.rbac.entity.Role;
import com.zl.rbac.entity.User;
import com.zl.rbac.entity.UserCondition;
import com.zl.rbac.exception.RbacException;
import com.zl.rbac.mapper.PermissionMapper;
import com.zl.rbac.mapper.UserMapper;
import com.zl.rbac.mapper.UserRoleMapper;
import com.zl.rbac.service.IUserService;
import com.zl.rbac.util.MD5;
import com.zl.rbac.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public Page<User> queryByPage(Integer pageIndex, Integer pageSize) throws Exception {
        Page<User> page = new Page<>(pageIndex, pageSize);
        //设置排序, 根基id升序排序
        page.addOrder(new OrderItem("id", true));
        userMapper.selectPage(page, null);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Serializable id) throws Exception {
        //删除用户信息
        userMapper.deleteById(id);
        //删除中间表信息
        userRoleMapper.deleteByUserId((Integer)id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(User user) throws Exception {
        userMapper.insert(user);
    }

    @Override
    public void update(User user) throws Exception {
        userMapper.updateById(user);
    }

    @Override
    public User queryById(Serializable id) throws Exception {
        return userMapper.selectById(id);
    }

    @Override
    public List<User> queryAll() throws Exception {
        return userMapper.selectList(null);
    }

    @Override
    public Page<User> queryUserAndRolesByPage(Integer pageIndex, Integer pageSize, UserCondition userCondition) throws Exception {
        Page<User> page = new Page<>(pageIndex, pageSize);
        if (userCondition == null) {
            userCondition = new UserCondition();
        }
        userCondition.setStart((pageIndex - 1) * pageSize);
        userCondition.setPageSize(pageSize);

        page.setTotal(userMapper.queryCount(userCondition));//设置总记录数    select  count(1)  ....
        page.setRecords(userMapper.queryUserAndRoleByPage(userCondition));//设置当前页数据   select  ....


        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(User user, Integer[] roleIds) throws Exception {
        //保存用户
        this.save(user);
        //保存用户分配的角色
        if (roleIds != null && roleIds.length > 0) {
            for (Integer rid : roleIds) {
                userRoleMapper.insert(user.getId(), rid);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(User user, Integer[] roleIds) throws Exception {
        //修改角色信息
        this.update(user);

        //修改权限中间表
        //删除这个用户所有的角色
        userRoleMapper.deleteByUserId(user.getId());

        //重新添加角色
        if (roleIds != null && roleIds.length > 0) {
            for (Integer rid : roleIds) {
                userRoleMapper.insert(user.getId(), rid);
            }
        }
    }

    @Override
    public User queryUserAndRolesById(Integer userid) throws Exception {
        UserCondition  userCondition = new UserCondition();
        User user = new User();
        user.setId(userid);
        userCondition.setUser(user);
        userCondition.setPageSize(1);
        userCondition.setStart(0);

        return userMapper.queryUserAndRoleByPage(userCondition).get(0);
    }

    @Override
    public void login(String username, String password) throws RbacException, Exception {
        QueryWrapper<User>  queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username).eq("password", MD5.encode(password));
        User user = userMapper.selectOne(queryWrapper);
        if(user == null){  //登录失败
                throw  new RbacException("亲,您的用户名密码错误");
        }else{ //登录成功
            //把当前用户信息保存到session
            UserContext.setUserInSession(user);
            // 把用户拥有的权限表达式保存session
            Set<String>  permissionSet =  permissionMapper.queryExpressionSetByUserId(user.getId());
            UserContext.setExpressionInSession(permissionSet);
        }
    }
}
